home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / Apps / Utilities / Unix / WhosOnFirst / myMainObject.m < prev    next >
Text File  |  1992-12-26  |  9KB  |  360 lines

  1. #import "myMainObject.h"
  2. #import <appkit/ScrollView.h>
  3. #import <streams/streams.h>
  4. #import <utmp.h>
  5. #import <libc.h>
  6. #import <sys/param.h>
  7. #import <dpsclient/dpsNeXT.h>
  8.  
  9. extern id infoManager;
  10. int find();
  11. void enter();
  12. void clear_marks();
  13. void remove_unmarked();
  14.  
  15. /*===========================================================================
  16.  
  17.     File: myMainObject.m
  18.     Purpose:  This file replaces the file "myApp.m" in the previous 
  19.         version.  3.0 doesn't like sub-classes of NXApp.
  20.         This object does the work for determining who is on-line.
  21.         This object receives the appDidInit method signals other 
  22.         objects that this event occured.
  23.  
  24.     NOTE: All areas of code which deal with the TextToSpeech Kit have 
  25.         been put under conditional compilation.  If you do not 
  26.         have the TextToSpeech kit, simply comment out the flags 
  27.         in the Makefile.preamble file and this code should compile
  28.         for you.
  29.  
  30. ===========================================================================*/
  31.  
  32.  
  33. @implementation myMainObject
  34.  
  35. void who(DPSTimedEntry teNumber, double now, char *userData)
  36.  
  37. /* Call this function via the DPS Timed Entry */
  38.  
  39. {
  40. struct utmp temp;            /* Utmp structure. See utmp.h */
  41. char tempHost[MAXHOSTNAMELEN];
  42.  
  43.     clear_marks();                    /* Clear marked */
  44.     utmpFile = NXMapFile("/etc/utmp", NX_READONLY);    /* Map utmp file into memory */
  45.     if (utmpFile == NULL)
  46.     {
  47.         exit(0);
  48.     }
  49.     while( NXRead(utmpFile, &temp, sizeof(struct utmp)) !=0 )    /* Read next entry */
  50.     {
  51.         if (temp.ut_name[0] != '\000')                    /* Is is a real user? */
  52.         {
  53.             if (strlen(temp.ut_host)==0)
  54.             {
  55.                 gethostname(tempHost, MAXHOSTNAMELEN);
  56.                 enter(temp.ut_line, temp.ut_name, tempHost);    /* Yes, enter or affirm in list */
  57.             }
  58.             else
  59.                 enter(temp.ut_line, temp.ut_name, temp.ut_host);    /* Yes, enter or affirm in list */
  60.         }
  61.     }
  62.     remove_unmarked();                    /* Remove all un-referenced entries in 
  63.                                    the list */
  64.  
  65.     NXClose(utmpFile);                    /* Close utmp file */
  66. }
  67.  
  68. -appDidInit:sender
  69. {
  70. #ifdef SPEECH
  71. const char *appPath;
  72. char dictPath[256];
  73. #endif
  74.     /* Init Icon Position coordinates */
  75.     nextX = nextY = 0;
  76.  
  77.     /* Initialize List pointers */
  78.     last = users = NULL;
  79.  
  80.     /* Fudge.  C calls seem to need this */
  81.     c_self = self;
  82.  
  83.     DPSAddTimedEntry((double)5.0, (DPSTimedEntryProc) who, NULL, NX_BASETHRESHOLD);
  84.     infoManager = localInfoMgr;
  85.  
  86.     /* Read in Defaults */
  87.     [infoManager initDefaults];
  88.  
  89. #ifdef SPEECH
  90.     /* Get application directory and set up TTS Kit application dictionary */
  91.     appPath = [self appDirectory];
  92.     strcpy(dictPath, appPath);
  93.     strcat(dictPath, "/WhosOnFirst.preditor");
  94.  
  95.     /* Initialize the speech. Include the application dictionary.*/
  96.     [infoManager initSpeech:dictPath];
  97. #endif
  98.  
  99.     return(self);
  100. }
  101.  
  102. /*===========================================================================
  103.  
  104.     Method: appDirectory
  105.     Purpose: To determine the current working directory of this
  106.         application.  The TextToSpeech application dictionary is
  107.         located within WhosOnFirst.app.  To install this dictionary
  108.         into the search path of the TextToSpeech Kit, we must provide
  109.         the speech server with the full path.
  110.  
  111. ===========================================================================*/
  112.  
  113. -(const char *) appDirectory
  114. {
  115. static char appDirectory[256];
  116. FILE *process;
  117. char command[256];
  118. char *suffix;
  119.  
  120.     strcpy(appDirectory, NXArgv[0]);
  121.     if (appDirectory[0] == '/')
  122.     {               /* if absolute path */
  123.         if (suffix = rindex(appDirectory, '/'))
  124.             *suffix = '\000';                   /* remove executable name */
  125.     } 
  126.     else
  127.     {
  128.         sprintf(command, "which '%s'\n", NXArgv[0]);
  129.         process = popen(command, "r");
  130.         fscanf(process, "%s", appDirectory);
  131.         pclose(process);
  132.         if (suffix = rindex(appDirectory, '/'))
  133.             *suffix = '\000';                   /* remove executable name */
  134.         chdir(appDirectory);
  135.         getwd(appDirectory);
  136.     }
  137.     return ( (const char *) appDirectory);
  138. }
  139.  
  140. /*===========================================================================
  141.  
  142.     Method: newIconUser: name
  143.         tty: ttystr
  144.         host: hoststr
  145.         xcoord: x
  146.         ycoord: y
  147.  
  148.     Purpose: When a new user is detected, this method creats an icon
  149.         for him/her and puts the utmp information within its own
  150.         database.
  151.  
  152. ===========================================================================*/
  153.  
  154. -newIconUser: (const char *)name tty: (const char *)ttystr host: (const char *) hoststr xcoord: (float)x ycoord: (float)y
  155. {
  156. NXRect windowRect;
  157.  
  158.  
  159. #ifdef SPEECH
  160.     /* Tell infoManager to Speak */
  161.     [infoManager speakLoginMessage: name tty:ttystr host:hoststr];
  162. #endif
  163.  
  164.     iconWindow = [Window alloc];            /* Get a window instance */
  165.  
  166.     /* Calulate Screen Coordinates */
  167.     windowRect.origin.x = 4.0 + 64.0 * x;
  168.     windowRect.origin.y = 0.0 + 64.0 * y;
  169.     windowRect.size.height = windowRect.size.width = 64.0; /* Icon size 64x64 */
  170.  
  171.     /*Init the window content */
  172.     [iconWindow initContent: &windowRect style: NX_PLAINSTYLE
  173.          backing: NX_BUFFERED buttonMask:0  defer: YES];
  174.  
  175.     /* Get an IconView Instance */
  176.     icon = [[IconView alloc] init];
  177.  
  178.     /* Set IconView as the window's contentView */
  179.     [[iconWindow setContentView: icon] free];
  180.  
  181.     [iconWindow setDelegate:icon];        /* Make view the window's delegate */
  182.     [iconWindow makeFirstResponder:icon];    /* and first responder */
  183.  
  184.     [iconWindow addToEventMask:NX_MOUSEDOWNMASK];
  185.     
  186.     /* Add to window list */
  187.     [iconWindow makeKeyAndOrderFront:self];    
  188.  
  189.     [icon iconSetName: name];        /* Set icon variables */
  190.     [icon iconSetTty: ttystr];
  191.     [icon iconSetHostName: hoststr];
  192.  
  193.     return iconWindow;
  194. }
  195.  
  196. /*===========================================================================
  197.  
  198.     Method: terminate:sender
  199.  
  200.     Purpose:  The terminate method is sent here.  This object notifies 
  201.         other objects that the program is about to terminate
  202.  
  203. ===========================================================================*/
  204.  
  205. - terminate:sender
  206. {
  207.     [infoManager cleanUp];
  208.     [owner terminate:sender];
  209.     return self;
  210. }
  211.  
  212. /*===========================================================================
  213.  
  214.     Function: enter (tty, name, hostname)
  215.  
  216.     Purpose:  When a new user is detected, information about his/her
  217.         tty, login name, and hostname are kept in a small database.
  218.         This function enters the user information into the 
  219.         data structures.
  220.  
  221.     Structure: The data base is a simple linked-list.
  222.  
  223. ===========================================================================*/
  224.  
  225. void enter(tty,name, hostname)
  226. char *tty, *name, *hostname;
  227. {
  228. struct record *temp;
  229.  
  230.  
  231.     if (find(tty, name)==0)        /* If new entry, malloc space and put in list */
  232.     {
  233.         temp = (struct record *) malloc(sizeof (struct record ));
  234.         temp->next = NULL;
  235.  
  236.         /* New Icon */
  237.         temp->windowPointer = [c_self newIconUser: name tty: tty host: hostname
  238.                       xcoord: (float)nextX ycoord:(float) nextY];
  239.  
  240.         temp->x = (float)nextX;    /* Position Icon in "dock" */
  241.         temp->y = (float)nextY;
  242.         temp->marked = 1;    /* Mark icon as referenced */
  243.  
  244.         strcpy(temp->name, name);          /* User name */
  245.         temp->name[8] = '\000';
  246.         strcpy(temp->tty, tty);               /* TTY name */
  247.         strcpy(temp->hostname, hostname);    /* Hostname */
  248.  
  249.         if (last == NULL)    /* First entry in list (usually console) */
  250.         {
  251.             users = temp;
  252.             last = temp;
  253.         }
  254.         else            /* Not first entry in list */
  255.         {
  256.             last->next = temp;
  257.             last = temp;
  258.         }
  259.  
  260.         nextY++;        /* Update coordinate for next icon */
  261.         if (nextY>=12)
  262.         {
  263.             nextY = 0;
  264.             nextX++;
  265.         }
  266.     }
  267. }
  268.  
  269. void clear_marks()        /* Simply traverse list and clear "marked" item in struct */
  270. {
  271. struct record *temp;
  272.  
  273.     temp = users;
  274.     while (temp!=NULL)
  275.     {
  276.         temp->marked = 0;
  277.         temp = temp->next;
  278.     }
  279. }
  280.  
  281. void remove_unmarked()        /* Remove all items from the list which have not been referenced */
  282. {
  283. struct record *temp,*prev;
  284.  
  285.     nextX = nextY = 0;
  286.     temp = users;
  287.     prev = temp;
  288.     while (temp!=NULL)
  289.     {
  290.         if (temp->marked == 0)             /* Standard linked list removal algorithm */
  291.         {
  292.  
  293. #ifdef SPEECH
  294.             [infoManager speakLogoutMessage: temp->name tty:temp->tty host:temp->hostname];
  295. #endif
  296.             if (temp == users)        /* Remove head item */
  297.             {
  298.                 users = temp->next;
  299.                 [temp->windowPointer free];
  300.                 free(temp);
  301.                 temp = users->next;
  302.             }
  303.             if (temp == last)        /* Remove last item */
  304.             {
  305.                 last  = prev;
  306.                 prev -> next = NULL;
  307.                 [temp->windowPointer free];
  308.                 free(temp);
  309.                 temp = NULL;
  310.             }
  311.             else                /* Remove internal item */
  312.             {
  313.                 prev->next = temp->next;
  314.                 [temp->windowPointer free];
  315.                 free(temp);
  316.                 temp = prev->next;
  317.             }
  318.         }
  319.         else
  320.         {
  321.             temp->x = 4.0 + 64.0 * (float) nextX;    /* Calulate Screen Coordinates */
  322.             temp->y = 0.0 + 64.0 * (float) nextY;
  323.  
  324.             /* Reposition icon to new location */
  325.             [temp->windowPointer moveTo: temp->x : temp->y];
  326.             [[temp->windowPointer contentView] display];
  327.  
  328.             nextY++;    /* Calculate next icon position */
  329.             if (nextY>=12) 
  330.             {
  331.                 nextY = 0;
  332.                 nextX++;
  333.             }
  334.             prev = temp;
  335.             temp = temp->next;
  336.         }
  337.     }
  338. }
  339.  
  340. int find(tty,name)    /* Return a 1 if record with "name" and "tty" exists in the list */
  341.             /* Mark record as referenced so that it is not removed from the list */
  342. char *tty,*name;
  343. {
  344. struct record *temp;
  345.  
  346.     temp = users;        /* Head of list */
  347.     while(temp!=NULL)
  348.     {
  349.         if ((strncmp(temp->tty, tty,8)==0)&&(strncmp(temp->name,name,8) ==0))
  350.         {
  351.             temp->marked = 1;
  352.             return(1);
  353.         }
  354.         temp = temp->next;
  355.     }
  356.     return(0);
  357. }
  358.  
  359. @end
  360.